package com.health.mapp.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.alipay.api.response.AlipayTradeRefundResponse;
import com.health.db.model.EPayCashPayment;
import com.health.db.model.RegisterOrder;
import com.health.db.model.UserCardList;
import com.health.db.model.UserCardListExt;
import com.health.db.model.UserLIST;
import com.health.db.service.order.IEPayCashPaymentService;
import com.health.db.service.order.IRegisterOrderService;
import com.health.db.service.sm.IAlipayService;
import com.health.db.service.sm.IRongService;
import com.health.db.service.sm.ISMSSendService;
import com.health.db.service.sm.IWXPayService;
import com.health.db.service.user.IUserCardListService;
import com.health.db.service.user.IUserLISTService;
import com.health.mapp.bean.CancelOrderReq;
import com.health.mapp.bean.CancelOrderResp;
import com.health.mapp.bean.Header;
import com.health.mapp.utils.Constant;
import com.health.mapp.utils.DateUtils;
import com.health.mapp.utils.Response;
import com.health.mapp.utils.ResultCode;
import com.health.pay.tencent.protocol.refund.RefundReqData;
import com.health.pay.tencent.protocol.refund.RefundResData;

/**
 *  取消订单
 *  只可以用户取消
 *  用户在未支付前可以取消订单，支付后统一走退款流程
 *  取消订单后，订单状态由等待支付状态直接变为订单关闭状态
 * 注：缺少融云消息推送
 * 注：订单取消后，未向EPayCashPayment表中填充退费标识
 * @author HiRoad
 * 
 *
 */
public class CancelOrderImpl implements ActionInterface {
	
	//service import
	private IRegisterOrderService registerOrderService  ;
	private IUserLISTService userLISTService  ;
	private IWXPayService wXPayService;
	private IEPayCashPaymentService ePayCashPaymentService;
	private IAlipayService alipayService;
	private IUserCardListService userCardListService;
	private IRongService rongService  ; 
	private ISMSSendService sMSSendService;
	

	@Override
	public Response execute(Header header, Object reqBean) throws Exception {
		
		CancelOrderReq req = (CancelOrderReq) reqBean; 
		CancelOrderResp _resp = new CancelOrderResp();
		Long orderId = req.getOrderId();
		Long  userId =req.getUserId();
		
		//校验入参
		if (orderId==0) {
			_resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_ORDERID);
			_resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_ORDERID_NOTE);
			return _resp;
		}
		
		if (userId==0) {
			_resp.setErrorCode(ResultCode.OPERATION_LAKE_PARAMETER_USERID);
			_resp.setErrorMsg(ResultCode.OPERATION_LAKE_PARAMETER_USERID_NOTE);
			return _resp;
		}
	
			RegisterOrder  currRegisterOrder  =registerOrderService.selectSimpleSingleByOrderId(orderId);
			
			//判断订单状态
			if (currRegisterOrder==null) {
				_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
				_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
				return _resp;
			}
				
			int runStatusId=currRegisterOrder.getRunstatusid();
			long orderUserId=currRegisterOrder.getUserid();
			//判断类型，如果不是等待支付的订单，都不可以做订单取消操作
			//判断类型，待就诊和就诊中，都不可以做订单取消操作
			if ( !(runStatusId==Constant.CONSTANTS_ORDER_RUNSTATUS_ID_1.intValue()||runStatusId==Constant.CONSTANTS_ORDER_RUNSTATUS_ID_2.intValue())) 
			{
				if (runStatusId==Constant.CONSTANTS_ORDER_RUNSTATUS_ID_3.intValue()      //视屏咨询  
						&&currRegisterOrder.getRegistertypeid()==Constant.CONSTANTS_ORDER_TYPE_ID_3   //已接单
						&&DateUtils.isAfter(DateUtils.parseDate(DateUtils.formatDate(currRegisterOrder.getScheduleTime())+" 00:00:00"), DateUtils.now()) //是否是当天
						) {
					//隔天的视屏咨询可以无偿取消 把状态设置成为待就诊
					currRegisterOrder.setRunstatusid(2);
					runStatusId =Constant.CONSTANTS_ORDER_RUNSTATUS_ID_2;
				}else{
				
				_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3016);
				_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3016_NOTE);
				return _resp;
				}
			}
			if ( !(orderUserId==userId.longValue())) 
			{
			 
				_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
				_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
				return _resp;
			}
			
			EPayCashPayment ePayCashPayment = null;
			currRegisterOrder.setRunStatus(Constant.CONSTANTS_ORDER_RUNSTATUS_DES_6);
			currRegisterOrder.setRunstatusid(Constant.CONSTANTS_ORDER_RUNSTATUS_ID_6);
			currRegisterOrder.setUpdateDate(DateUtils.now());
					
			if(currRegisterOrder.getOrderfeetypeid().intValue()!=Constant.CONSTANTS_ORDER_FREE_ID_0.intValue()
					&&runStatusId==Constant.CONSTANTS_ORDER_RUNSTATUS_ID_2.intValue()&&currRegisterOrder.getRegisterTotal().compareTo(new BigDecimal(0))>0){
				Short payTypeId = currRegisterOrder.getPayTypeId();
				
				//微信退款
				if(payTypeId.intValue()==Constant.CONSTANTS_PAYMENT_WEIXIN)	{
					
					List<EPayCashPayment> ePayCashPaymentList = ePayCashPaymentService.selectByOrderId(orderId);
					if (ePayCashPaymentList.size()!=1) {
						//信息错误
						_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
						_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
						return _resp;
					}else{
						
							ePayCashPayment = ePayCashPaymentList.get(0);
							int fee = ePayCashPayment.getPaycashTotal().multiply(new BigDecimal(100)).intValue();
							RefundReqData refundReqData = new RefundReqData(
									ePayCashPayment.getBankCashIdno(), ePayCashPayment.getPaycashIdno(), null,
									ePayCashPayment.getPaycashIdno(),fee,fee, null, null);
							RefundResData refundResData = wXPayService.refund(refundReqData);
							
							String resultCode = refundResData.getResult_code();
							
							//SUCCESS 微信取消成功
							if (StringUtils.isNotBlank(resultCode)&&resultCode.equals("SUCCESS")) {
								
								//更新回调日志表
								EPayCashPayment ePayCashPaymentForUpdate = new EPayCashPayment();
								ePayCashPaymentForUpdate.setPaycashid(ePayCashPayment.getPaycashid());
								ePayCashPaymentForUpdate.setPaycashIdno(ePayCashPayment.getPaycashIdno()+"R");
								ePayCashPaymentForUpdate.setPaycashSign(Constant.CONSTANTS_IS_PAYMENT_CANCEL);
								ePayCashPaymentService.updateByPayCashIDSelective(ePayCashPayment,ePayCashPaymentForUpdate,currRegisterOrder);
							}else{
								//信息错误
								_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3005);
								_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3005_NOTE);
								return _resp;
							}
					}
					
				//支付宝退款	
				}else if (payTypeId.intValue()==Constant.CONSTANTS_PAYMENT_ALIPAY) {
								
					
					
					List<EPayCashPayment> ePayCashPaymentList = ePayCashPaymentService.selectByOrderId(orderId);
					if (ePayCashPaymentList.size()!=1) {
						//信息错误
						_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
						_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
						return _resp;
					}else{
						
						ePayCashPayment =  ePayCashPaymentList.get(0);
						AlipayTradeRefundResponse  AlipayTradeRefundResponse 
						=alipayService.refund(ePayCashPayment.getPaycashIdno(), ePayCashPayment.getBankCashIdno(), 
											 String.valueOf(ePayCashPayment.getPaycashTotal().setScale(2)),
											 null, null, null, null, null);
						
						String resultCode = AlipayTradeRefundResponse.getCode();
						
						//10000 支付宝取消接口
						if (StringUtils.isNotBlank(resultCode)&&resultCode.equals("10000")) {
						
						//更新回调日志表
						EPayCashPayment ePayCashPaymentForUpdate = new EPayCashPayment();
						ePayCashPaymentForUpdate.setPaycashid(ePayCashPayment.getPaycashid());
						ePayCashPaymentForUpdate.setPaycashIdno(ePayCashPayment.getPaycashIdno()+"R");
						ePayCashPaymentForUpdate.setPaycashSign(Constant.CONSTANTS_IS_PAYMENT_CANCEL);
						ePayCashPaymentService.updateByPayCashIDSelective(ePayCashPayment,ePayCashPaymentForUpdate,currRegisterOrder);	
						}else{
							//订单错误
							_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3005);
							_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3005_NOTE);
							return _resp;
						}
					}
					
				//健康卡退款	
				}else if (payTypeId.intValue()==Constant.CONSTANTS_PAYMENT_SERVICE_CARD) {	
					
					//图文咨询
					if (currRegisterOrder.getRegistertypeid()==Constant.CONSTANTS_ORDER_TYPE_ID_1) {
						 
						long cardId=Long.valueOf(currRegisterOrder.getCardID());
						//查到具体是哪张卡里扣减的
						UserCardList  userCardList =userCardListService.selectByCardId(cardId);
						
						if(null!=userCardList){
						
						userCardList.setLefttime01(userCardList.getLefttime01().add(new BigDecimal(1)));
						registerOrderService.updateOrder4CardRefound(currRegisterOrder, userCardList);
						}else{
							//信息错误
							_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
							_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
							return _resp;
						}
					}
					else
					{
						String[] cardIds=currRegisterOrder.getCardID().split(",");
						//多条批处理
						if (cardIds.length==1) {
							//查到具体是哪张卡里扣减的
							UserCardList  userCardList =userCardListService.selectByCardId(Long.valueOf(currRegisterOrder.getCardID()));
							
							if(null!=userCardList){
								
								userCardList.setLefttime03(userCardList.getLefttime03().add(new BigDecimal(currRegisterOrder.getCardJournalAmount())));
								registerOrderService.updateOrder4CardRefound(currRegisterOrder, userCardList);
								
							}else{
								//信息错误
								_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
								_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
								return _resp;
							}
						}else{
							
							String[] cardLeftTime=currRegisterOrder.getCardJournalAmount().split(",");
							
							UserCardListExt example = new UserCardListExt();
							example.setOwnerid(currRegisterOrder.getUserid());
							//查询所有的cardList
							List<UserCardList> userCardLists =userCardListService.selectUserCardLists(example);
							//需要更新的表
							List<UserCardList> userCardListsForUpdate = new ArrayList<UserCardList>();
							Map<String,UserCardList> map = new HashMap<String, UserCardList>();
							for (int i = 0; i < userCardLists.size(); i++) {
								UserCardList card = userCardLists.get(i);
								map.put(String.valueOf(card.getCardid()), card);
							}
							
							for (int i = 0; i < cardIds.length; i++) {
								
								//查到具体是哪张卡里扣减的
								UserCardList  userCardList =map.get(cardIds[i]);
								 //剩余时间
								userCardList.setLefttime03(userCardList.getLefttime03().add(new BigDecimal(cardLeftTime[i])));
								userCardListsForUpdate.add(userCardList);
							}
							registerOrderService.updateOrder4CardRefound(currRegisterOrder, userCardListsForUpdate);
						}
					}
				
				//健康卡end
					
				}else if(payTypeId==Constant.CONSTANTS_PAYMENT_WALLET){
					
					//查看是否有卡支付 (卡中有余额)
					if (StringUtils.isNotEmpty(currRegisterOrder.getCardJournalAmount())) {
						
						String[] cardIds=currRegisterOrder.getCardID().split(",");
						//多条批处理
						if (cardIds.length==1) {
							//查到具体是哪张卡里扣减的
							UserCardList  userCardList =userCardListService.selectByCardId(Long.valueOf(currRegisterOrder.getCardID()));
							
							if(null!=userCardList){
								
								userCardList.setLefttime02(userCardList.getLefttime02().add(new BigDecimal(currRegisterOrder.getCardJournalAmount())));
								registerOrderService.updateOrder4WalletAndCardRefound(currRegisterOrder, userCardList);
								
							}else{
								//信息错误
								_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
								_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
								return _resp;
							}
						}else{
							
							String[] cardLeftTime=currRegisterOrder.getCardJournalAmount().split(",");
							
							UserCardListExt example = new UserCardListExt();
							example.setOwnerid(currRegisterOrder.getUserid());
							//查询所有的cardList
							List<UserCardList> userCardLists =userCardListService.selectUserCardLists(example);
							//需要更新的表
							List<UserCardList> userCardListsForUpdate = new ArrayList<UserCardList>();
							Map<String,UserCardList> map = new HashMap<String, UserCardList>();
							for (int i = 0; i < userCardLists.size(); i++) {
								UserCardList card = userCardLists.get(i);
								map.put(String.valueOf(card.getCardid()), card);
							}
							
							for (int i = 0; i < cardIds.length; i++) {
								
								//查到具体是哪张卡里扣减的
								UserCardList  userCardList =map.get(cardIds[i]);
								 //剩余时间
								userCardList.setLefttime02(userCardList.getLefttime02().add(new BigDecimal(cardLeftTime[i])));
								userCardListsForUpdate.add(userCardList);
							}
							registerOrderService.updateOrder4WalletAndCardRefound(currRegisterOrder, userCardListsForUpdate);
						}
						
					}else{
						//仅钱包支付
						registerOrderService.updateOrder4WalletRefound(currRegisterOrder);
					}
				}else{
					//信息错误
					_resp.setErrorCode(ResultCode.OPERATION_ORDER_ERROR_3001);
					_resp.setErrorMsg(ResultCode.OPERATION_ORDER_ERROR_3001_NOTE);
					return _resp;
				}
			}
			
			registerOrderService.updateOrder4Cancel(currRegisterOrder);
			
			//视屏咨询
			if (currRegisterOrder.getRegistertypeid().intValue()!=Constant.CONSTANTS_ORDER_TYPE_ID_1.intValue()&&
					currRegisterOrder.getRegistertypeid().intValue()!=Constant.CONSTANTS_ORDER_TYPE_ID_4.intValue()
			) {
				//SendSMS(currRegisterOrder);
				UserLIST docUser = userLISTService.selectByUserId(currRegisterOrder.getAccepterid());
				sMSSendService.cancleOrder(docUser, currRegisterOrder);
			}
				
		_resp.setErrorCode(ResultCode.OPERATION_SUCCESS);
		_resp.setErrorMsg(ResultCode.OPERATION_SUCCESS_NOTE);
 
		return _resp;
	}

	public IRegisterOrderService getRegisterOrderService() {
		return registerOrderService;
	}

	public void setRegisterOrderService(IRegisterOrderService registerOrderService) {
		this.registerOrderService = registerOrderService;
	}

	public IUserLISTService getUserLISTService() {
		return userLISTService;
	}

	public void setUserLISTService(IUserLISTService userLISTService) {
		this.userLISTService = userLISTService;
	}

	/**
	 * @return the wXPayService
	 */
	public IWXPayService getwXPayService() {
		return wXPayService;
	}

	/**
	 * @param wXPayService the wXPayService to set
	 */
	public void setwXPayService(IWXPayService wXPayService) {
		this.wXPayService = wXPayService;
	}

	/**
	 * @return the ePayCashPaymentService
	 */
	public IEPayCashPaymentService getePayCashPaymentService() {
		return ePayCashPaymentService;
	}

	/**
	 * @param ePayCashPaymentService the ePayCashPaymentService to set
	 */
	public void setePayCashPaymentService(
			IEPayCashPaymentService ePayCashPaymentService) {
		this.ePayCashPaymentService = ePayCashPaymentService;
	}

	/**
	 * @return the alipayService
	 */
	public IAlipayService getAlipayService() {
		return alipayService;
	}

	/**
	 * @param alipayService the alipayService to set
	 */
	public void setAlipayService(IAlipayService alipayService) {
		this.alipayService = alipayService;
	}

	/**
	 * @return the userCardListService
	 */
	public IUserCardListService getUserCardListService() {
		return userCardListService;
	}

	/**
	 * @param userCardListService the userCardListService to set
	 */
	public void setUserCardListService(IUserCardListService userCardListService) {
		this.userCardListService = userCardListService;
	}

	/**
	 * @return the rongService
	 */
	public IRongService getRongService() {
		return rongService;
	}

	/**
	 * @param rongService the rongService to set
	 */
	public void setRongService(IRongService rongService) {
		this.rongService = rongService;
	}

	public ISMSSendService getsMSSendService() {
		return sMSSendService;
	}

	public void setsMSSendService(ISMSSendService sMSSendService) {
		this.sMSSendService = sMSSendService;
	}
	
}
